package cn.com.shopec.erp.financing.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.shopec.erp.common.constant.SZSCMConstant;
import cn.com.shopec.erp.common.page.PageFinder;
import cn.com.shopec.erp.common.page.PageQuery;
import cn.com.shopec.erp.common.utils.DateUtil;
import cn.com.shopec.erp.common.utils.LogicUtil;
import cn.com.shopec.erp.common.utils.StringUtil;
import cn.com.shopec.erp.financing.dao.ISupplierSettlementDao;
import cn.com.shopec.erp.financing.dao.ISupplierSettlementDetailDao;
import cn.com.shopec.erp.financing.entity.SupplierSettlement;
import cn.com.shopec.erp.financing.entity.SupplierSettlementDetail;
import cn.com.shopec.erp.financing.service.ISupplierSettlementService;
import cn.com.shopec.erp.financing.vo.SupplierSettlementVo;
import cn.com.shopec.erp.purchase.dao.IPurchaseOrderDao;
import cn.com.shopec.erp.purchase.dao.IPurchaseReturnOrderDao;
import cn.com.shopec.erp.purchase.entity.PurchaseOrder;
import cn.com.shopec.erp.purchase.entity.PurchaseReturnOrder;

@Service
public class SupplierSettlementServiceImpl implements ISupplierSettlementService {

	@Resource
	private ISupplierSettlementDao supplierSettlementDao;

	@Resource
	private ISupplierSettlementDetailDao supplierSettlementDetailDao;

	@Resource
	private IPurchaseOrderDao purchaseOrderDao;

	@Resource
	private IPurchaseReturnOrderDao purchaseReturnOrderDao;

	@Override
	public PageFinder<SupplierSettlement> supplierSettlementPageList(SupplierSettlementVo supplierSettlementVo, PageQuery pageQuery) {
		DetachedCriteria detachedCriteria = supplierSettlementDao.createCriteria();
		if (supplierSettlementVo != null) {
			if (StringUtil.isExist(supplierSettlementVo.getSupplierNo())) {
				detachedCriteria.add(Restrictions.eq("supplierNo", supplierSettlementVo.getSupplierNo()));
			}
			if (StringUtil.isExist(supplierSettlementVo.getSettlementNo())) {
				detachedCriteria.add(Restrictions.eq("settlementNo", supplierSettlementVo.getSettlementNo()));
			}
			if (StringUtil.isExist(supplierSettlementVo.getSettlementStartTime())) {
				detachedCriteria.add(Restrictions.ge("settlementTime", DateUtil.parseDate(supplierSettlementVo.getSettlementStartTime(),"yyyy-MM-dd")));
			}
			if (StringUtil.isExist(supplierSettlementVo.getSettlementEndTime())) {
				try {
					detachedCriteria.add(Restrictions.lt("settlementTime", DateUtil.parseDate(DateUtil.getDateNextDay(supplierSettlementVo.getSettlementEndTime()),"yyyy-MM-dd")));
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}
			if (StringUtil.isExist(supplierSettlementVo.getCheckState())) {
				detachedCriteria
						.add(Restrictions.eq("checkState", Integer.valueOf(supplierSettlementVo.getCheckState())));
			}
		}
		detachedCriteria.addOrder(Order.desc("settlementTime"));
		if(pageQuery == null){
			int totalRows = 0;
			List<SupplierSettlement> list = supplierSettlementDao.findByCriteria(detachedCriteria);
			if(list != null && list.size()>0){
				totalRows = list.size();
			}
			PageFinder<SupplierSettlement> pageFinder = new PageFinder<SupplierSettlement>(1, totalRows, totalRows);
			pageFinder.setData(list);
			return pageFinder;
		}
		return supplierSettlementDao.pagedByCriteria(detachedCriteria, pageQuery.getPage(), pageQuery.getPageSize());
	}

	@Override
	public PageFinder supplierSettlementDetailPageList(SupplierSettlementVo supplierSettlementVo, PageQuery pageQuery) {
		/*
		 * DetachedCriteria detachedCriteria =
		 * supplierSettlementDetailDao.createCriteria(); if
		 * (supplierSettlementVo != null) { if
		 * (StringUtil.isExist(supplierSettlementVo.getSettlementNo())) {
		 * detachedCriteria.add(Restrictions.eq("settlementNo",
		 * supplierSettlementVo.getSettlementNo())); } } return
		 * supplierSettlementDetailDao.pagedByCriteria(detachedCriteria,
		 * pageQuery.getPage(), pageQuery.getPageSize());
		 */
		return supplierSettlementDetailDao.supplierSettlementDetailPageList(supplierSettlementVo, pageQuery);
	}

	@Transactional
	@Override
	public String createSupplierSettlement(String start, String end) {
		String msg = SZSCMConstant.SUCCESS;
		try {
			if (StringUtil.isExist(start) && StringUtil.isExist(end)) {
				DetachedCriteria poDetachedCriteria = purchaseOrderDao.createCriteria();
				poDetachedCriteria.add(Restrictions.ge("createTime", start));
				poDetachedCriteria.add(Restrictions.le("createTime", end));
				poDetachedCriteria.add(Restrictions.in("auditResult", new Integer[] { 1 }));
				poDetachedCriteria
						.add(Restrictions.or(Restrictions.eq("isSettled", 0), Restrictions.isNull("isSettled")));
				List<PurchaseOrder> pos = purchaseOrderDao.findByCriteria(poDetachedCriteria);
				DetachedCriteria proDetachedCriteria = purchaseReturnOrderDao.createCriteria();
				proDetachedCriteria.add(Restrictions.ge("createTime", start));
				proDetachedCriteria.add(Restrictions.le("createTime", end));
				proDetachedCriteria.add(Restrictions.in("auditResult", new Integer[] { 1 }));
				proDetachedCriteria
						.add(Restrictions.or(Restrictions.eq("isSettled", 0), Restrictions.isNull("isSettled")));
				List<PurchaseReturnOrder> pros = purchaseReturnOrderDao.findByCriteria(proDetachedCriteria);

				Map posMap = new HashMap();
				Map poNamesMap = new HashMap();
				for (PurchaseOrder po : pos) {
					if (LogicUtil.isNotNull(po.getTotalPrice())) {
						BigDecimal totalPrice = BigDecimal.valueOf(po.getTotalPrice())
								.add(posMap.get(po.getSupCode()) != null ? (BigDecimal) posMap.get(po.getSupCode())
										: BigDecimal.ZERO);
						posMap.put(po.getSupCode(), totalPrice);
						poNamesMap.put(po.getSupCode(), po.getSupName());
					}
				}

				for (PurchaseReturnOrder pro : pros) {
					if (LogicUtil.isNotNull(pro.getTotalPrice())) {
						BigDecimal totalPrice = BigDecimal.valueOf(-Double.parseDouble(pro.getTotalPrice()))
								.add(posMap.get(pro.getSupCode()) != null ? (BigDecimal) posMap.get(pro.getSupCode())
										: BigDecimal.ZERO);
						posMap.put(pro.getSupCode(), totalPrice);
						poNamesMap.put(pro.getSupCode(), pro.getSupName());
					}
				}

				Iterator it = posMap.keySet().iterator();
				while (it.hasNext()) {
					String supCode = (String) it.next();
					String supName = poNamesMap.get(supCode) != null ? (String) poNamesMap.get(supCode) : "";
					BigDecimal totalPrice = (BigDecimal) posMap.get(supCode);
					SupplierSettlement supplierSettlement = new SupplierSettlement();
					String settlementNo = new Date().getTime() + "";
					supplierSettlement.setSupplierNo(supCode);
					supplierSettlement.setSupplierName(supName);
					supplierSettlement.setSettlementNo(settlementNo);
					supplierSettlement.setStartDate(DateUtil.parseDate(start, DateUtil.TIMESTAMP_PATTERN));
					supplierSettlement.setEndDate(DateUtil.parseDate(end, DateUtil.TIMESTAMP_PATTERN));
					supplierSettlement.setSettlementTime(new Date());
					supplierSettlement.setDeleteFlag(0);
					supplierSettlement.setCreateTime(new Date());
					supplierSettlement.setUpdateTime(new Date());
					supplierSettlement.setSettlementTotal(totalPrice);
					supplierSettlementDao.save(supplierSettlement);

					for (PurchaseOrder po : pos) {
						if (supCode.equals(po.getSupCode())) {
							SupplierSettlementDetail supplierSettlementDetail = new SupplierSettlementDetail();
							supplierSettlementDetail.setSettlementNo(settlementNo);
							supplierSettlementDetail.setPoNo(po.getPoNo());
							supplierSettlementDetail.setPoType(1);
							supplierSettlementDetailDao.save(supplierSettlementDetail);
							po.setIsSettled(1);
							purchaseOrderDao.update(po);
						}
					}

					for (PurchaseReturnOrder pro : pros) {
						if (supCode.equals(pro.getSupCode())) {
							SupplierSettlementDetail supplierSettlementDetail = new SupplierSettlementDetail();
							supplierSettlementDetail.setSettlementNo(settlementNo);
							supplierSettlementDetail.setPoNo(pro.getPuNo());
							supplierSettlementDetail.setPoType(2);
							supplierSettlementDetailDao.save(supplierSettlementDetail);
							pro.setIsSettled(1);
							purchaseReturnOrderDao.update(pro);
						}
					}
				}

			} else {
				msg = SZSCMConstant.FAIL;

			}
		} catch (Exception e) {
			msg = SZSCMConstant.FAIL;
			e.printStackTrace();
		}
		return msg;
	}

	@Transactional
	@Override
	public String checkSupplierSettlement(SupplierSettlementVo supplierSettlementVo) {
		String msg = SZSCMConstant.SUCCESS;
		try {
			if (supplierSettlementVo != null) {
				SupplierSettlement supplierSettlement = new SupplierSettlement();
				if (StringUtil.isExist(supplierSettlementVo.getSettlementId())) {
					supplierSettlement.setSettlementId(supplierSettlementVo.getSettlementId());
					if (StringUtil.isExist(supplierSettlementVo.getCheckState())) {
						supplierSettlement.setCheckState(Integer.valueOf(supplierSettlementVo.getCheckState()));
						supplierSettlement.setCheckTime(new Date());
						supplierSettlement.setUpdateTime(new Date());
						// 审核不通过改变采购单结算标识为否
						if (Integer.valueOf(supplierSettlementVo.getCheckState()) == 2) {
							SupplierSettlementDetail ssd = new SupplierSettlementDetail();
							ssd.setSettlementNo(supplierSettlementVo.getSettlementNo());
							List list = supplierSettlementDetailDao.findSettlementDetailByNo(ssd);
							// 修改采购单和退货单结算状态
							for (Object object : list) {
								SupplierSettlementDetail getSsd = (SupplierSettlementDetail) object;
								PurchaseReturnOrder pro = purchaseReturnOrderDao.findUniqueBy("poNo", getSsd.getPoNo());
								if (pro != null) {
									pro.setIsSettled(0);
									purchaseReturnOrderDao.update(pro);
								}
								PurchaseOrder po = purchaseOrderDao.findUniqueBy("poNo", getSsd.getPoNo());
								if (po != null) {
									po.setIsSettled(0);
									purchaseOrderDao.update(po);
								}
							}
						}
					}
					supplierSettlementDao.updateSupplierSettlement(supplierSettlement);

				}

			} else {
				msg = SZSCMConstant.FAIL;
			}
		} catch (Exception e) {
			msg = SZSCMConstant.FAIL;
			e.printStackTrace();
		}
		return msg;
	}

}
